# 两两交换链表中的节点： https://leetcode-cn.com/problems/swap-nodes-in-pairs/submissions/

class ListNode:
    def __init__(self, val=0, next=None):
        self.val = val
        self.next = next


# 我的一种写法
class Solution:
    def swapPairs(self, head: ListNode) -> ListNode:
        """
            首先需要交换两个元素，并且插入原来的位置。 需要动三个指针
            n1, n2 表示两个 节点， pre 表示 n1 前面的节点

            1. n1.next = n2.next
            2. n2.next = n1
            3. pre.next = n2

            指针后移：
            pre = n1
            n1 = n1.next
            n2 = n1.next

            # 因为需要动用两个元素前面的指针，所以需要定义一个 首元结点
        """
        # 长度小于1， 直接返回
        if not head or not head.next:
            return head

        # 首元结点
        dumpy = ListNode(0, head)
        pre = dumpy
        n1, n2 = head, head.next
        # 必须都有， 只有n1的话， 就不需要动
        while n1 and n2:
            n1.next = n2.next
            n2.next = n1
            pre.next = n2

            pre = n1
            n1 = n1.next
            if n1 is not None:
                n2 = n1.next
            else:
                break
        
        return dumpy.next
        

# while 循环的优化写法， 太好了！
"""
    如果像上面我写的，先定义了 n1, n2, 到最后的判断，很难直到， n1, n2 谁为None，或者都为None
    而先判断 pre， 再去定义 n1, n2。 就不会出现这样的情况， 下面对 n1, n2的赋值，以及 pre 更新为 pre.next.next 均在上面的while判断条件内！！
    太妙了~~~~， 赞
"""
while pre.next and pre.next.next:
            n1 = pre.next
            n2 = pre.next.next

            # 反转，连接
            n1.next = n2.next
            n2.next = n1
            pre.next = n2

            pre = pre.next.next
            
            